package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.lang.model.element.VariableElement;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 菜品表
 */
@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     *
     * 1.接受传递过来数据
     *      分页
     *      条件
     * 2.调用service查询
     *
     * Dish菜品  与  category套餐分类
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){
        Page<DishDto> dishDtoPage = dishService.pageWithCateory(page, pageSize, name);
        return R.success(dishDtoPage);
    }

    /**
     *
     *添加
     * 添加之后redis 中的数据与数据库中的不一致
     *   将redis 中的数据删除
     *   重新查询数据库
     *
     * @return
     */
    @Transactional
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        //将key 定义出来
        String key = "dish" + dishDto.getCategoryId() + "_1";

        //将redis 中的key删除
        redisTemplate.delete(key);

        dishService.saveWithFlavor(dishDto);
        return R.success("添加菜品成功");
    }


    /**
     *
     *  删除菜品  dish（菜品）表与SetmealDish（套餐表）
     *  1.状态
     *      判断状态是否为停售状态
     *  2.是否关联套餐
     *
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids){
        log.info("传回来要删除的ids：{}",ids);
        dishService.deleteWithSetmealDish(ids);
        return R.success("删除成功");
    }



    /**
     *  根据id 查询
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> getById(@PathVariable Long id){
        Dish dish = dishService.getById(id);
        //创建dishDto对象
        DishDto dishDto = getDishDto(dish);
        return R.success(dishDto);
    }



    /**
     *修改菜品
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        dishService.updateWithFlavor(dishDto);
        return R.success("修改成功");
    }

    /*
     *   TODO
     *  将redis 中的菜品数据返回
     * 查询redis
     *  如果没有查询数据库
     *       然后将菜品数据添加到redis 中
     *
     *  查询菜品时将菜品和口味一起查询返回
     *  1.根据传回来的Id
     *  2.名称 状态  根据分类Id精确查询
     *  3.根据sort正序排序    根据修改时间倒序排序
     *  4.查询口味
     * @param dish
     * @return
     */
    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish) {
        //创建一个返回对象
        List<DishDto> dishDtoList = null;

        // 将key 定义出来
        String key = "dish" + dish.getCategoryId() + "_" +dish.getStatus();

        //根据key 查询redis
        dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);

        //判断
        if(dishDtoList != null){

            //如果不为null 代表查出来数据 将结果返回
            return R.success(dishDtoList);
        }

        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        //根据名称模糊查询
        lqw.like(StringUtils.isNotEmpty(dish.getName()), Dish::getName, dish.getName());
        //根据分类id精确查询
        lqw.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
        //根据售卖状态查询（查询启售状态）
        lqw.eq(Dish::getStatus, 1);
        //排序，根据sort正序排序，再根据修改时间倒叙排序
        lqw.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        //查询
        List<Dish> list = dishService.list(lqw);

        List<DishDto> resultList = list.stream().map(dishItem -> {
            DishDto dishDto=getDishDto(dishItem);
            return dishDto;
        }).collect(Collectors.toList());

        //redis 中不存在数据  查询数据库 将查出来的数据存进 redis 中 并设置到期时间
        redisTemplate.opsForValue().set(key, resultList, 24, TimeUnit.HOURS );

        return R.success(resultList);
    }

    /**
     *  修改状态
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    public R<String> status(@RequestParam List<Long> ids,@PathVariable Integer status){
        Dish dish = new Dish();
        dish.setStatus(status);
        LambdaQueryWrapper<Dish> dishLqw = new LambdaQueryWrapper<>();
        dishLqw.in(Dish::getId,ids);
        dishService.update(dish,dishLqw);
        return R.success("修改成功");
    }


    private DishDto getDishDto(Dish dish) {

        DishDto dishDto = new DishDto();
        //将dish中的数据复制到dishDto中
        BeanUtils.copyProperties(dish,dishDto);
        LambdaQueryWrapper<DishFlavor> dflqw = new LambdaQueryWrapper<>();
        dflqw.eq(dish.getId() != null, DishFlavor::getDishId,dish.getId());
        List<DishFlavor> list = dishFlavorService.list(dflqw);
        dishDto.setFlavors(list);
        return dishDto;
    }
}
